package JasPerl::JSTL::Core::ForEachTag;

use 5.010;
use strict;
use warnings;

use parent qw(JasPerl::JSTL::Core::LoopTagSupport);

use JasPerl::JSTL::Core::Exceptions;
use JasPerl::Util::Enumeration;

my %ITEMS = (
    '' => sub {
        return JasPerl::Util::Enumeration->from_list(split ',', $_[0]);
    },
    'ARRAY' => sub {
        return JasPerl::Util::Enumeration->from_list(@{$_[0]});
    },
    'HASH' => sub {
        return JasPerl::Util::Enumeration->from_list(
            map { { key => $_, value => $_[0]->{$_} } } keys %{$_[0]}
        );
    }
);

sub set_begin {
    $_[0]->{begin} = int($_[1]);
    $_[0]->validate_begin();
}

sub set_step {
    $_[0]->{step} = int($_[1]);
    $_[0]->validate_step();
}

sub set_end {
    $_[0]->{end} = int($_[1]);
    $_[0]->validate_end();
}

sub set_items {
    $_[0]->{items} = $_[1];
}

sub prepare {
    my $self = shift;
    if (not exists $self->{items}) {
        $self->{enum} = JasPerl::Util::Enumeration->from_list(
            0 .. $self->{end} // -1
        );
    } elsif (not defined $self->{items}) {
        $self->{enum} = JasPerl::Util::Enumeration::EMPTY_ENUMERATION;
    } elsif (exists $ITEMS{ref $self->{items}}) {
        $self->{enum} = $ITEMS{ref $self->{items}}->($self->{items});
    } elsif (eval { $self->{items}->isa('JasPerl::Util::Enumeration') }) {
        $self->{enum} = $self->{items};
    } else {
        JasPerl::JSTL::Core::IllegalAttributeTypeException->throw(
            'forEach', 'items', ref $self->{items}
        );
    }
}

sub has_next {
    return $_[0]->{enum}->has_next();
}

sub next {
    return $_[0]->{enum}->next();
}

1;
